var verify = function(upData) {
	//console.log('进入verify, 数据：', upData);
	if (upData == null || upData == "") {
		return ResponseVo.error("数据为空");
	}
	upData = upData.toUpperCase();

	if (!upData.startsWith("6A")) {
		return ResponseVo.error("非法数据，启始位非6A");
	}

	var dataLength = upData.length;
	if (dataLength % 2 != 0) {
		return ResponseVo.error("HEX字符数必须为偶数");
	}


	var byteNum = dataLength / 2;

	var hexLength = takeHex(upData, 9, 1);
	var length = hexToInt(hexLength);
	if ((byteNum - 11) != length) {
		return ResponseVo.error("长度" + hexLength + "不正确 upData=" + upData);
	}

	var command = "";
	var mac = "";
	var length = "";
	var random = "";
	var param = "";
	var check = "";

	mac = takeHex(upData, 1, 8);
	command = takeHex(upData, 14, 1);
	length = takeHex(upData, 9, 1);
	random = takeHex(upData, 10, 4);
	param = takeHex(upData, 15, byteNum - 15 - 1);
	check = takeHex(upData, byteNum + (byteNum - 1), 1);
	//console.log(mac, command, length, random, param, check);
	var agree = new AgreeInfo(mac, command, length, random, param, check);
	//console.log("agree的值：", agree);
	return ResponseVo.success(agree);
}

var down = function(mac, command, param) {
	mac = mac == (null || undefined) ? "" : mac;
	command = command == (null || undefined) ? "" : command;
	param = param == (null || undefined) ? "" : param;
	var random = randomNum(10000000, 99999999);
	var randomStr = random.toString().padStart(8, '0');
	var check = makeChecksum(randomStr + command + param);
	return downData(mac, command, randomStr, param, check);
}
var downData = function(mac, command, random, param, check) {
	mac = mac == (null || undefined) ? "" : mac;
	command = command == (null || undefined) ? "" : command;
	random = random == (null || undefined) ? "" : random;
	param = param == (null || undefined) ? "" : param;
	check = check == (null || undefined) ? "" : check;
	mac = mac.padStart(16, '0');
	command = command.padStart(2, '0');
	var length = 16 + param.length / 2;
	//console.log('param length', param.length);
	//console.log('length', length);
	var hexLength = intToHex(length);
	var data = "6A" + mac + hexLength + random + command + param + check;

	// console.log("mac=" + mac + " hexLength=" + hexLength + " random=" + random + " command=" + command + " param=" +
	// 	param + " check=" + check);
	return data;
}


var intToHex = function(val) {
	var hex = parseInt(val).toString(16);
	return hex;
}
var hexToInt = function(hex) {
	var val = parseInt(hex, 16);
	return val;
}

function stringToHex(str) {
	var val = "";
	for (var i = 0; i < str.length; i++) {
		if (val == "")
			val = str.charCodeAt(i).toString(16);
		else
			val += "," + str.charCodeAt(i).toString(16);
	}
	return val;
}

var takeHex = function(hex, off, length) {
	try {
		if (hex == null || hex.length % 2 != 0) {
			return "";
		}
		if ((off * 2 + length * 2) > hex.length) {
			return "";
		}
		var beginIndex = off * 2;
		var endIndex = beginIndex + length * 2;
		return hex.substring(beginIndex, endIndex);
	} catch (e) {}
	return "";
}

function randomNum(minNum, maxNum) {
	switch (arguments.length) {
		case 1:
			return parseInt(Math.random() * minNum + 1, 10);
		case 2:
			return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
		default:
			return 0;
	}
}
//累加校验和 累加之后取低字节
var makeChecksum = function(data) {
	if (data == null || data == "") {
		return "";
	}
	if (data.length % 2 != 0) {
		return "";
	}
	var total = 0;
	var len = data.length;
	var num = 0;
	while (num < len) {
		var s = data.substring(num, num + 2);
		total += hexToInt(s);
		num = num + 2;
	}

	var mod = total % 256;
	var hex = intToHex(mod);
	len = hex.length;
	if (len < 2) {
		hex = "0" + hex;
	}
	return hex;
}
var padLeft = function(ret, padChar, len) {
	if (padChar == undefined || padChar == null) {
		padChar = "";
	}
	while (ret.length < len) {
		if (ret.length + padChar.length < len) {
			ret = padChar + ret;
		} else {
			ret = padChar.substring(0, len - ret.length) + ret;
		}

	}
	return ret;
};
var padRight = function(ret, padChar, len) {
	while (ret.length < len) {
		if (ret.length + padChar.length < len) {
			ret += padChar;
		} else {
			ret += padChar.substring(0, len - ret.length);
		}
	}
	return ret;
}
var dateFormat = function(d) {
	//var d = new Date();
	var curr_date = d.getDate();
	var curr_month = d.getMonth() + 1;
	var curr_year = d.getFullYear();
	var curr_hour = d.getHours();
	var curr_minutes = d.getMinutes();
	var curr_seconds = d.getSeconds();
	String(curr_month).length < 2 ? (curr_month = "0" + curr_month) : curr_month;
	String(curr_date).length < 2 ? (curr_date = "0" + curr_date) : curr_date;

	String(curr_hour).length < 2 ? (curr_hour = "0" + curr_hour) : curr_hour;
	String(curr_minutes).length < 2 ? (curr_minutes = "0" + curr_minutes) : curr_minutes;
	String(curr_seconds).length < 2 ? (curr_seconds = "0" + curr_seconds) : curr_seconds;

	var yearStr = String(curr_year);
	yearStr = yearStr.substring(2);
	var yyMMddHHmmss = yearStr + "" + curr_month + "" + curr_date + curr_hour + curr_minutes + curr_seconds;
	return yyMMddHHmmss;
}

function AgreeInfo(mac, command, length, random, param, check) {
	this.mac = mac;
	this.command = command;
	this.length = length;
	this.random = random;
	this.param = param;
	this.check = check;
}
class ResponseVo {
	constructor(code, message, data) {
		this.code = code;
		this.message = message;
		this.data = data;
	}
	static success(data) {
		this.code = 0;
		this.message = "";
		this.data = data;
		return new ResponseVo(this.code, this.message, this.data);
	}
	static error(message) {
		this.code = 1;
		this.message = message;
		this.data = null;
		return new ResponseVo(this.code, this.message, this.data);
	}
}
module.exports = {
	down: down,
	verify: verify,
	intToHex: intToHex,
	hexToInt: hexToInt,
	takeHex: takeHex,
	padLeft: padLeft,
	stringToHex: stringToHex
}
